<!--多文件上传表格组件,使用示例<AntFormUpload label="附件" :v-decorator="['fileId']" :data="{tableName: 'sys_file'}"></AntFormUpload>-->
<template>
  <a-form-item :label="label">
    <a-input
        readOnly
        ref="input"
        v-decorator="vDecorator"
        :style="getStyle"
        :placeholder="!isDisabled?cplaceholder:''"
        :class="{'c-form-disabled':isDisabled,'c-form-input':true}"
        @mouseover="onmouseover"
        @mouseout="onmouseout"
    ></a-input>
    <!--已上传文件列表-->
    <div
        ref="cFileTable"
        class="c-file-table"
        :style="'width:'+(width?width:(tablePosition.width+'px'))+';top:'+tablePosition.top+'px;left:'+tablePosition.left+'px;'"
        v-show="mouseIn&&dataSource.length>0"
        @mouseenter="onmouseover"
        @mouseleave="onmouseout"
    >
      <AntTable
          ref="mainTable"
          tableMoveInfoFields="originalName"
          :tableMoveable="!isDisabled"
          :autoLoad="false"
          :pageable="false"
          :tableSort="false"
          :tableShowSetting="false"
          :tableShowNumber="tableShowNumber"
          :autoCalcVisible="false"
          :tableHeight="tableHeight"
          :table-title="tableTitle"
          @rowDrag="rowDrag"
      >
        <template v-slot:action="info">
          <AntTableButtonGroup>
            <a @click="filePreview(info.row)" :disabled="showPreview(info.row)">预览</a>
            <a @click="download(info.row)">下载</a>
            <a v-if="!isDisabled" @click="deleteFile(info.row)">删除</a>
          </AntTableButtonGroup>
        </template>
      </AntTable>
    </div>
    <AntUpload
        @change="uploadChange"
        :multiple="multiple"
        :disabled="isDisabled"
        :data="data"
        :accept="accept"
    >
      <a-button v-if="!isDisabled" :disabled="isDisabled" type="primary">
        <a-icon v-if="iconShow" type="upload"/>
        上传
      </a-button>
    </Antupload>
  </a-form-item>
</template>

<script>
import './css/form.less'
import { mixin } from './js/form.js'

// 附件表格
const tableTitle = [
  {
    title: '名称',
    field: 'originalName'
  },
  {
    title: '操作',
    field: 'action',
    type: 'custom',
    name: 'action',
    width: 120,
    fixed: 'right'
  }
]

export default {
  name: 'AntFormUpload',
  mixins: [mixin],
  props: {
    /**
     * 是否禁用
     */
    disabled: {
      type: Boolean,
      default: false
    },
    /**
     * 是否由form表单自动布局
     */
    autoLayoutByForm: {
      type: Boolean,
      default: true
    },
    /**
     * 显示文本
     */
    label: {
      type: String,
      default: ''
    },
    /**
     * 输入提示
     */
    placeholder: {
      type: String,
      default: ''
    },
    /**
     * 允许上传的文件类型
     */
    accept: {
      type: String,
      default: '.txt,.xls,.xlsx,.doc,.docx,.pfd,.zip,.ppt,.pptx,.rar,.png,.jpg,.pdf'
    },
    /**
     * 多文件上传
     */
    multiple: {
      type: Boolean,
      default: true
    },
    /**
     * 附件上传时需要传递到后台的参数
     */
    data: {
      type: Object,
      default: () => {
        return {
          tableName:null
        }
      }
    },
    /**
     * 绑定字段 ['phone' ,{ rules: [{ required: true},{validator:function(rule, value, callback)] }],自定义验证方法时callback回调函数必须在方法中调用，
     * 失败返回错误提示callback("xxx")，成功返回callback()
     * 字段值多个逗号隔开
     */
    vDecorator: {
      type: Array,
      default: () => []
    },
    /**
     * 是否显示上传图标
     */
    iconShow: {
      type: Boolean,
      default: true
    },
    /**
     * 是否显示序号列
     */
    tableShowNumber: {
      type: Boolean,
      default: false
    },
    /**
     * 表格自定义宽度 null：自适应父级
     */
    width: {
      type: String,
      default: null
    },
    /**
     * css样式，优先级最高
     */
    cstyle: {
      type: String,
      default: ''
    },
    /**
     * 非自动布局的宽度，优先级最低
     */
    defaultWidth: {
      type: Number,
      default: 240
    }
  },
  data() {
    return {
      //是否禁用和输入提示，由AntForm组件调用
      cdisabled: false,
      cplaceholder: this.placeholder ? this.placeholder : '请上传' + this.label,
      dataSource: [],
      // 鼠标是否移入
      mouseIn: false,
      // 表格标题栏
      tableTitle: tableTitle,
      // 表格每行默认高度
      tableHeight: 32,
      // 表格位置
      tablePosition: {
        top: 0,
        left: 0,
        width: null
      }
    }
  },
  computed: {
    /**
     * 获取样式
     */
    getStyle() {
      return { width: (this.percentageLayoutWidth ? this.percentageLayoutWidth : this.defaultWidth) + 'px', ...this.cstyle }
    }
  },
  mounted() {
    // 自动添加验证为空时的message
    let vDecorator = this.vDecorator
    if (vDecorator.length > 1 && vDecorator[1].rules) {
      let rules = vDecorator[1].rules
      rules.forEach(obj => {
        if (obj.required && !obj.message) {
          obj.message = '请选择' + this.label
        }
      })
    }
    // 自动加载表格dom
    this.reloadDomOnBody()
    // 表格操作区域大小 - 删除
    if (this.isDisabled) {
      this.tableTitle[1].width = 100
    } else {
      this.tableTitle[1].width = 120
    }
  },
  watch: {
    /**
     * 修改dataSource数组后，更新from表单域的值
     */
    dataSource: {
      handler(newValue, oldValue) {
        let str = ''
        for (let i = 0; i < this.dataSource.length; i++) {
          str += this.dataSource[i].originalName + '；'
        }
        const c = this.getParentForm(this.$parent)
        let key = this.vDecorator[0]
        const record = {}
        record[key] = str
        c.setFieldsValue(record)
        this.reloadTableHeight()
        this.$refs.mainTable.setTableData(this.dataSource, this.dataSource.length)
      },
      deep: true
    }
  },
  beforeDestroy() {
    // 销毁表格dom
    this.$refs.cFileTable.remove()
  },
  methods: {
    /**
     * 页面挂载初始化，将dom挂载到body上 - 只挂载一次
     */
    reloadDomOnBody() {
      if (document.body.append) {
        // 在IE11中 document.appendChild会报错: javascript runtime error:HierarchyRequestError
        document.body.append(this.$refs.cFileTable)
      } else {
        document.body.appendChild(this.$refs.cFileTable)
      }
    },
    /**
     * 加载数据源
     */
    loadDataById(fileIds, callBack) {
      this.dataSource = []
      this.$getAction('/file/getByFileId', { fileIds: fileIds }).then(res => {
        this.dataSource = res.data
        if (callBack) {
          callBack()
        }
      })
    },
    /**
     * 获取数据源用于保存
     */
    getDataSource() {
      return this.dataSource
    },
    /**
     * 鼠标移入，显示附件列表
     */
    onmouseover() {
      // 计算当前表格dom的位置
      const rect = this.$refs.input.$el.getBoundingClientRect()
      console.log(rect.left)
      this.tablePosition = {
        top: rect.bottom + 5,
        left: rect.left,
        width: rect.width
      }
      this.mouseIn = true

      this.reloadTableHeight()
    },
    /**
     * 鼠标移出，隐藏附件
     */
    onmouseout() {
      // 恢复表格dom
      this.tablePosition = {
        top: 0,
        left: 0,
        width: null
      }
      this.mouseIn = false
    },
    /**
     * 上传文件结束后
     */
    uploadChange(obj) {
      if (obj.file.status === 'uploading') {
      }
      // 上传完成（固定写法）
      if (obj.file.status === 'done' && obj.file.response.code === 200) {
        this.$message.success('上传成功')
        this.dataSource.push(obj.file.response.data)
      } else if (obj.file.status === 'done' && obj.file.response.success === false) {
        this.$message.error('上传失败')
      }
    },
    /**
     * 删除附件
     */
    deleteFile(record) {
      let dataSource = this.dataSource
      // 如果有id则表示已保存在数据库，需要进行数据库删除
      if (record.fileId) {
        this.$deleteAction(`/file/deleteByFileId`, { fileIds: record.fileId })
      }
      for (let i = 0; i < dataSource.length; i++) {
        if (record === dataSource[i]) {
          dataSource.splice(i, 1)
          break
        }
      }
    },
    /**
     * 附件预览
     * @param record
     */
    filePreview(record) {
      if (!record.fileId) {
        this.$message.warning('附件未保存，无法预览')
        return
      }
      this.$downloadAction(`/file/preViewFileByFileId`, { fileId: record.fileId }, null,"get",true)
    },
    /**
     * 附件下载
     * @param record
     */
    download(record) {
      if (!record.fileId) {
        this.$message.warning('附件未保存，无法下载')
        return
      }
      this.$downloadAction(`/file/downloadByFileId`, { fileId: record.fileId }, record.originalName,"get")
    },
    /**
     * 赋值之前的转换操作,由AntForm组件自动调用
     * 参数：recordPara，转换之前的record
     * 返回值：转换之后的可用于赋值的对象
     */
    beforeSetValue(recordPara) {
      let key = this.vDecorator[0]
      let val = recordPara[key]
      // 根据附件id加载附件信息
      if (val && val.length > 0) {
        this.loadDataById(val)
      }
      return {}
    },
    /**
     * 取值之前的转换操作,由AntForm组件自动调用
     * 参数：recordPara，转换之前的record
     * 返回值：转换之后的对象
     */
    beforeGetValue(recordPara) {
      let record = {}
      let key = this.vDecorator[0]
      let idStr = ''
      for (let i = 0; i < this.dataSource.length; i++) {
        let obj = this.dataSource[i]
        idStr += obj.fileId + ','
      }
      if (idStr.length > 0) {
        idStr = idStr.substring(0, idStr.length - 1)
      }
      record[key] = idStr
      return record
    },
    /**
     * 获取父级form表单
     */
    getParentForm(param) {
      if (param.$refs.aform) {
        return param.$refs.aform.form
      } else {
        return this.getParentForm(param.$parent)
      }
    },
    /**
     * 清空组件值
     */
    resetField() {
      this.dataSource = []
    },
    /**
     * 判断预览按钮是否可用
     * @param record
     * @returns {boolean}
     */
    showPreview(record) {
      return !['.doc', '.docx', '.txt', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.png', '.jpg'].find(
          el => record.originalName.indexOf(el) > -1
      )
    },
    /**
     * 拖拽行移动成功
     */
    rowDrag() {
      this.dataSource = this.$refs.mainTable.getTableData()
    },
    /**
     * 重构表格高度
     */
    reloadTableHeight() {
      if (this.dataSource.length < 10) {
        this.tableHeight = this.dataSource.length * 32 + 10
      } else {
        this.tableHeight = 320
      }
      const rect = this.$refs.input.$el.getBoundingClientRect()
      const maxHeight = document.documentElement.clientHeight - rect.bottom - 60
      if (this.tableHeight > maxHeight) {
        this.tableHeight = maxHeight > 0 ? maxHeight : 0
      }
    }
  }
}
</script>

<style lang="less" scoped>
::v-deep .ant-btn.ant-btn-primary {
  position: absolute;
  right: 0px;
  top: 4px;
  border-radius: 0 4px 4px 0;
}

::v-deep .ant-form-item-children {
  position: relative;
  display: block;
}

::v-deep .itemClass {
  display: flex;
  flex-flow: row nowrap;
  justify-content: flex-start;
}

.itemClass:hover {
  background: #e6f7ff;
}

::v-deep .textClass {
  padding-left: 8px;
  overflow: hidden;
}

::v-deep .btnClass {
  padding-left: 10px;
  margin-right: 5px;
  width: 3em;
}

::v-deep .btnClass .btnDel {
  color: #ff2525;
}

.c-file-table {
  position: absolute;
  z-index: 3000;
  width: 100%;
  margin-top: -4px;
  border: 1px ridge #cfcfcf;
}
</style>
